import { expandFor } from '@/components/Expandable';

export function set(object, keys = []) {
  return (value) => {
    let keyList = keys;
    if (!Array.isArray(keys)) keyList = [keyList];
    keyList = keyList?.slice() ?? [];
    if (!keyList.length) return false;

    const last = keyList.pop();
    let target = object;
    for (const key of keyList) {
      if (typeof key === 'function') {
        target = key(target);
      } else {
        target = target?.[key];
      }
      if (target == null) return false;
    }

    if (typeof target === 'object' && target != null) {
      target[last] = value;
      return true;
    }

    return false;
  };
}

export function get(keys) {
  return (object) => {
    let keyList = keys;
    if (!Array.isArray(keyList)) keyList = [keyList];

    let result = object;
    for (const key of keyList) {
      if (typeof key === 'function') {
        result = key(result);
      } else {
        result = result?.[key];
      }
      if (result == null) break;
    }
    return result;
  };
}

export function pull(...items) {
  return (array) => {
    if (!Array.isArray(array)) return null;
    const array2 = array.slice();
    items.forEach((item) => {
      const index = array2.indexOf(item);
      if (index > -1) array2.splice(index, 1);
    });
    return array2;
  };
}

export function replace(target, replacement) {
  return (array) => {
    const array2 = array.slice();
    const index = array2.indexOf(target);
    if (index > -1) array2.splice(index, 1, replacement);
    return array2;
  };
}

export function push(...items) {
  return (array) => array.concat(items);
}

export function call(...args) {
  return (fn) => () => fn?.(...args);
}

export function concat(...arg1) {
  let args = arg1.slice();
  const c = (...arg2) => {
    args = args.concat(arg2);
    return c;
  };
  c.get = () => args;
  return c;
}

export function invert(fn) {
  return (...args) => !fn(...args);
}

/**
 * 返回一个catch函数，在字段校验失败的时候滚动到第一个校验失败字段
 * @param form
 * @return {function(*): Promise<void>}
 */
export function catchAndScrollFor(form) {
  return async (error) => {
    const { errorFields } = error;
    const fieldName = errorFields[0].name;
    const fieldInstance = form.getFieldInstance(fieldName);
    if (fieldInstance) {
      await expandFor(document.getElementById(fieldInstance.id));
      form.scrollToField(fieldName, { behavior: 'smooth', block: 'center' });
    }
    throw error;
  };
}
